package org.dromara.web.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.NetbarConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.enums.FormatsType;
import org.dromara.common.core.utils.AssertUtils;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.RedisKeyGeneratorUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.netbar.domain.bo.*;
import org.dromara.netbar.domain.vo.NetbarClientVo;
import org.dromara.netbar.domain.vo.NetbarCouponMemberVo;
import org.dromara.netbar.domain.vo.NetbarMemberVo;
import org.dromara.netbar.service.INetbarClientService;
import org.dromara.netbar.service.INetbarCouponMemberService;
import org.dromara.netbar.service.INetbarMemberService;
import org.dromara.netbar.service.impl.CouponService;
import org.dromara.netbar.service.impl.MemberService;
import org.dromara.netbar.util.CouponUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 客户端可用接口
 * @author ZhouWenTao
 * @create 2025-08-05 11:30
 */
@Slf4j
@SaIgnore
@RequiredArgsConstructor
@RestController
@RequestMapping("/auth/v1/netbar")
public class AuthNetbarV1Controller {
    @Resource
    private INetbarClientService netbarClientService;
    @Resource
    private INetbarMemberService netbarMemberService;
    @Resource
    private MemberService memberService;
    @Resource
    private INetbarCouponMemberService netbarCouponMemberService;
    @Resource
    private CouponService couponService;

    @PostMapping("/client/bind")
    public R<NetbarClientVo> bindClient(@Validated @RequestBody NetbarClientBo bo) {
        /*if (StringUtils.isEmpty(bo.getClientNo())) {
            return R.fail("请输入客户端编号");
        }*/
        String macAddress = bo.getMacAddress();
        if (StringUtils.isEmpty(macAddress)) {
            return R.fail("请输入MAC地址");
        }
        if (StringUtils.isEmpty(bo.getTenantId())) {
            return R.fail("请选择租户");
        }
        if (StringUtils.isEmpty(bo.getAppVersion())) {
            return R.fail(NetbarConstants.Client.ERROR_CODE.CLIENT_VERSION_OLD,"客户端版本已停用");
        }
        AssertUtils.isTrue("v1.0".equals(bo.getAppVersion()), "请使用最新客户端版本");
        NetbarClientVo netbarClientVo = netbarClientService.getClientByMacAddress(bo.getTenantId(), bo.getMacAddress());
        if (null == netbarClientVo) {
            return R.fail(NetbarConstants.Client.ERROR_CODE.CLIENT_STATUS_NOT,"当前电脑未绑定至服务端，请联系管理员进行绑定");
        }
        if ("9".equals(netbarClientVo.getStatus())) {
            return R.fail(NetbarConstants.Client.ERROR_CODE.CLIENT_STATUS_STOP,"该客户端已停用");
        }
        if("1".equals(netbarClientVo.getStatus())){
            return R.fail(NetbarConstants.Client.ERROR_CODE.CLIENT_STATUS_BOUND,"该客户端已绑定");
        }
        if("2".equals(netbarClientVo.getStatus())){
            return R.fail(NetbarConstants.Client.ERROR_CODE.CLIENT_STATUS_USING,"该客户端使用中");
        }
        // 修改客户机状态已开机绑定状态
        // netbarClientService.bindClientOpen(bo.getTenantId(), netbarClientVo.getClientId());
        return R.ok("连接成功", netbarClientVo);
    }

    /**
     * 登录
     */
    @PostMapping("/member/login")
    public R<?> loginClient(@Validated @RequestBody NetbarMemberLoginBo bo) {
        AssertUtils.notNull(bo.getAccount(), "请输入账号");
        AssertUtils.notNull(bo.getPassword(), "请输入密码");
        AssertUtils.notNull(bo.getClientId(), "请选择电脑");
        AssertUtils.notNull(bo.getTenantId(), "租户信息有误");
        NetbarMemberVo member = netbarMemberService.getMember(bo.getTenantId(), bo.getAccount());
        AssertUtils.notNull(member, "该会员信息不存在");
        AssertUtils.isTrue(member.getPassword().equals(bo.getPassword()), "密码错误");
        bo.setMemberId(member.getMemberId());
        String onlineMemberKey = RedisKeyGeneratorUtils.getOnlineMemberKey(bo.getTenantId());
        Map<String,Object> redisData = RedisUtils.getCacheMapValue(onlineMemberKey, member.getMemberId().toString());
        if(redisData != null){
            long clientId = (Long) redisData.get("clientId");
            if (clientId == bo.getClientId()) {
                return R.ok("账号重连", redisData);
            }
            return R.fail("账号已在其他电脑登录");
        }
        Map<String, Object> data = memberService.openClient(bo);
        //TODO 写入客户端登录日志
        if (data == null) {
            return R.fail("登录失败");
        }
        return R.ok("登录成功",data);
    }

    /**
     * 下机接口
     */
    @PostMapping("/member/logout")
    public R<?> logout(@RequestBody NetbarMemberBo bo) {
        return R.ok(netbarMemberService.offline(bo));
    }


    /**
     * 获取卡券
     */
    @PostMapping("/member/coupons")
    public R<?> couponList(@RequestBody NetbarMemberLoginBo bo) {
        AssertUtils.notNull(bo.getMemberId(), "会员ID不能为空");
        long currentTimeMillis = System.currentTimeMillis();
        String nowDateStr = DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, new Date());
        List<NetbarCouponMemberVo> netbarCouponMemberVos = netbarCouponMemberService.listCouponMemberGroupByMemberIds(Collections.singletonList(bo.getMemberId()), nowDateStr);
        for (NetbarCouponMemberVo cmRecord : netbarCouponMemberVos) {
            if(null != cmRecord.getCoupon() && CouponUtils.checkCouponBsValid(cmRecord.getCoupon(), currentTimeMillis)){
                cmRecord.setAvailable(true);
            }
        }
        Map<String, Object> resultMaps = new HashMap<>();
        // 自动使用优惠券
        resultMaps.put("autoCouponMemberList", netbarCouponMemberVos.stream().filter(c -> c.getCoupon().getIsAutoUse() == 1 && c.getMemberId().equals(bo.getMemberId())).toList());
        resultMaps.put("manualCouponMemberList", netbarCouponMemberVos.stream().filter(c -> c.getCoupon().getIsAutoUse() == 2 && c.getMemberId().equals(bo.getMemberId())).toList());
        return R.ok(resultMaps);
    }

    /**
     * 使用卡券
     * @param bo {memberId 用户Id,couponId 卡券Id}
     */
    @PostMapping("/member/useCoupon")
    public R<?> use(@RequestBody NetbarCouponMemberBo bo) {
        R<?> r = couponService.useCoupon(bo);
        memberService.refreshMemberRedis(bo.getTenantId(), bo.getMemberId());
        return r;
    }

    /**
     * 修改密码
     */
    @PostMapping("/member/updatePassword")
    public R<?> updatePassword(@RequestBody NetbarMemberUpdatePasswordBo bo) {
        // TODO 密码修改
        AssertUtils.notNull(bo.getMemberId(), "会员不能为空");
        AssertUtils.notNull(bo.getOldPassword(), "旧密码不能为空");
        AssertUtils.notNull(bo.getNewPassword(), "新密码不能为空");
        // 先获取之前的数据
        NetbarMemberVo member = netbarMemberService.queryById(bo.getMemberId());
        AssertUtils.notNull(member, "会员信息不存在");
        AssertUtils.isTrue(member.getPassword().equals(bo.getOldPassword()), "旧密码错误");
        netbarMemberService.updateMemberPassword(bo.getMemberId(), bo.getNewPassword());
        return R.ok("修改成功");
    }
}
